#!/usr/bin/env python
# -*- coding: utf-8 -*-

# 记录常用的算法


"""
二分查找法
"""


def two_part_find(inputNum, numRange):
    """
    二分查找法
    :param inputNum: 指定数字元素
    :param numRange:  type list 数字组成的列表
    :return:
    """

    mdindex = len(numRange) // 2
    if len(numRange) == 1:
        if numRange[0] != inputNum:
            raise Exception("列表中未找到 : %s " % inputNum)
    elif numRange[mdindex] == inputNum:
        print("元素%s 在列表中的位置是：%s" % (inputNum, mdindex))
        return mdindex
    elif numRange[mdindex] < inputNum:
        print("以 %s 为界取 后半段" % str(numRange[mdindex]))
        two_part_find(inputNum, numRange[mdindex + 1:])
    elif numRange[mdindex] > inputNum:
        print("以 %s 为界取 前半段" % str(numRange[mdindex]))
        two_part_find(inputNum, numRange[:mdindex])
    else:
        raise Exception("here")


# two_part_find(8, [1, 2, 5, 7, 9, 12, 55])


"""
冒泡排序
"""


def list_sort(num_list):
    """
    将数字列表从小到大排序,并返回
    :param num_list:
    :return:
    """
    for indx, numx in enumerate(num_list):
        for indy, numy in enumerate(num_list[:-1]):
            if numy > num_list[indy + 1]:
                # num_list[indy + 1],num_list[indy] = num_list[indy],num_list[indy + 1]
                a = num_list[indy + 1]
                num_list[indy + 1] = num_list[indy]  # 不能等于numy，是浅拷贝
                num_list[indy] = a
    print(num_list)
    return num_list


# list_sort(num_list=[3, 1, 4, 6,7, 5, 2])


"""
判断字符中每个字符是否唯一，或去掉不唯一的字符
"""


def demo(string):
    """

    :param string:
    :return:
    """
    before = len(string)
    parser_set = set(string)  # 在集合中，所有的元素都是唯一的。你可以使用 set() 方法将字符串、
    # 列表等任何「可迭代对象」转换为集合，转换后会删除重复的元素，继而长度会发生变化。
    after = len(parser_set)
    if before == after:
        return True
    else:
        return False


# res =  demo("rde")
# print(res)

"反转字符串"


def reverse_string(string):
    cstring = string[-1::-1]
    print(cstring)
    return cstring


# reverse_string(string="de3231cd32a2bu")


"""给定一个整数 num，从 1 到 num 按照下面的规则返回每个数：
如果这个数被 3 整除，返回 'Fizz'。
如果这个数被 5 整除，返回 'Buzz'。
如果这个数能同时被 3 和 5 整除，返回 'FizzBuzz'。
如果这个数既不能被 3 也不能被 5 整除，返回这个数字的字符串格式。
"""


def fizz_buzz(num):
    if num is None:
        raise TypeError('num cannot be None')
    if num < 1:
        raise ValueError('num cannot be less than one')
    results = []
    for i in range(1, num + 1):
        if i % 3 == 0 and i % 5 == 0:
            results.append('FizzBuzz')
        elif i % 3 == 0:
            results.append('Fizz')
        elif i % 5 == 0:
            results.append('Buzz')
        else:
            results.append(str(i))
    return results


"""
求最大公约数
"""


def divideNum02(n1, n2):
    if n1 % n2 == 0:
        return n2
    else:
        return divideNum02(n2, n1 % n2)


# 递推法求1-n的和
def sum01(n):
    result = 0
    for i in range(1, n + 1):
        result += i
    return result


"""
生成器：能够展开嵌套列表
"""
nested = [[1, 2], [2, 3], [5, 5], [6]]


def flatten(nested):
    for sublist in nested:
        for element in sublist:
            yield element


"""
上面只能展开2层，如果要适配无限层：
递归生成器
"""


def flatten2(nested):
    try:
        for sublist in nested:
            for element in flatten2(sublist):
                yield element
    except TypeError:
        print("here")
        yield nested

for i in flatten2(nested):
    print(i)